package com.zhilei.controller;

import com.zhilei.base.BaseInfoProperties;
import com.zhilei.grace.result.GraceJSONResult;
import com.zhilei.mq.DelayConfig_Industry;
import com.zhilei.pojo.Industry;
import com.zhilei.pojo.bo.IndustryBO;
import com.zhilei.pojo.vo.IndustryVO;
import com.zhilei.service.IndustryService;
import com.zhilei.untils.GsonUtils;
import com.zhilei.untils.LocalDateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.simpleframework.xml.core.Validate;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 创建行业类别
 *
 * @author 志磊
 * @serial 2024-09-22
 */
@Slf4j
@RestController
@RequestMapping("industry")
public class IndustryController extends BaseInfoProperties {

    public final Integer THIRD_NODE = 3;
    public final Integer SECOND_NODE = 2;
    public final Integer FIRST_NODE = 1;

    @Autowired
    private IndustryService industryService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 创建一级行业类别
     *
     * @param industryBO
     * @return
     */
    @PostMapping("createNode")
    public GraceJSONResult createNode(@RequestBody @Validate IndustryBO industryBO) {

        // TODO 查询行业类别是否存在
        boolean nodeName = industryService.getIndustryIsExistByName(industryBO.getName());
        if (nodeName) {
            return GraceJSONResult.errorMsg("行业类别已存在！");
        }

        // TODO 创建行业类别更新redis的数据
        Industry industry = new Industry();
        BeanUtils.copyProperties(industryBO, industry);

        // TODO 重置缓存
        // resetRedisIndustry(industry);

        // TODO 创建行业类别
        industryService.createNode(industryBO);

        return GraceJSONResult.ok();
    }

    /**
     * 查询其他分类节点的数据
     *
     * @return
     */
    @GetMapping("children/{industryByFatherId}")
    public GraceJSONResult getChildren(@PathVariable("industryByFatherId") String industryByFatherId) {

        // TODO 查询行业类别是否存在
        if (StringUtils.isBlank(industryByFatherId)) {
            return GraceJSONResult.errorMsg("参数不能为空！");
        }

        // TODO 查询行业类别
        List<Industry> industryList = industryService.getIndustryIsExistByFatherId(industryByFatherId);

        List<IndustryVO> IndustryVOList = new ArrayList<>();

        for (Industry Industry : industryList) {
            IndustryVO industryVO = new IndustryVO();
            BeanUtils.copyProperties(Industry, industryVO);
            IndustryVOList.add(industryVO);
        }

        return GraceJSONResult.ok(IndustryVOList);
    }

    /**
     * 更新分类
     *
     * @param industryBO
     * @return
     */
    @PostMapping("updateNode")
    public GraceJSONResult updateNode(@RequestBody @Validate IndustryBO industryBO) {

        // TODO 查询行业类别是否存在
        boolean nodeName = industryService.getIndustryIsExistByName(industryBO.getName());
        if (nodeName) {
            return GraceJSONResult.errorMsg("行业类别已存在！");
        }

        // TODO 创建行业类别更新redis的数据
        Industry industry = new Industry();
        BeanUtils.copyProperties(industryBO, industry);

        // TODO 重置缓存
        // resetRedisIndustry(industry);

        // TODO 更新行业类别
        industryService.updateIndustry(industryBO);

        return GraceJSONResult.ok();
    }

    /**
     * 删除节点数据
     *
     * @param industryByFatherId
     * @return
     */
    @DeleteMapping("deleteNode/{industryByFatherId}")
    public GraceJSONResult deleteNode(@PathVariable("industryByFatherId") String industryByFatherId) {

        // TODO 查询行业类别是否存在
        if (StringUtils.isBlank(industryByFatherId)) {
            return GraceJSONResult.errorMsg("参数不能为空！");
        }

        // TODO 如果是第三级节点直接删除否则的话那就删除子节点在删除父节点
        Industry industry = industryService.getIndustryById(industryByFatherId);
        if (industry.getLevel().equals(THIRD_NODE)) {
            industryService.deleteIndustry(industryByFatherId);
        }

        // TODO 如果分层登记是一个2
        if (industry.getLevel().equals(SECOND_NODE) || industry.getLevel().equals(FIRST_NODE)) {
            // TODO 查询父id有没有相等的
            List<Industry> industryList = industryService.getIndustryBySecondId(industryByFatherId);
            // TODO 如果集合里面没有存在的数据就直接删除
            if (industryList == null || industryList.isEmpty()) {
                industryService.deleteIndustry(industryByFatherId);
            } else {
                return GraceJSONResult.errorMsg("请先删除当前节点下的其他节点！");
            }
        }

        // TODO 重置缓存
        resetRedisIndustry(industry);

        return GraceJSONResult.ok();
    }

    /**
     * 查询顶级节点列表
     *
     * @return
     */
    @GetMapping("getTopList")
    public GraceJSONResult getTopList() {

        List<Industry> industryList = industryService.getTopIndustryList();
        List<IndustryVO> industryVOList = new ArrayList<>();

        for (Industry industry : industryList) {
            IndustryVO industryVO = new IndustryVO();
            BeanUtils.copyProperties(industry, industryVO);
            industryVOList.add(industryVO);
        }
        return GraceJSONResult.ok(industryVOList);
    }

    /**
     * 查询app端顶级节点列表
     *
     * @return
     */
    @GetMapping("app/initTopList")
    public GraceJSONResult initTopList() {

        String topIndustryListStr = redis.get(TOP_INDUSTRY_LIST);
        List<IndustryVO> industryVOList = new ArrayList<>();
        List<Industry> industryList = null;
        if (StringUtils.isNotBlank(topIndustryListStr)) {
            industryList = GsonUtils.stringToListAnother(topIndustryListStr, Industry.class);
            for (Industry industry : industryList) {
                IndustryVO industryVO = new IndustryVO();
                BeanUtils.copyProperties(industry, industryVO);
                industryVOList.add(industryVO);
            }
            return GraceJSONResult.ok(industryVOList);
        } else {
            industryList = industryService.getTopIndustryList();
            String topIndustryListString = GsonUtils.object2String(industryList);
            redis.set(TOP_INDUSTRY_LIST, topIndustryListString);
            for (Industry industry : industryList) {
                IndustryVO industryVO = new IndustryVO();
                BeanUtils.copyProperties(industry, industryVO);
                industryVOList.add(industryVO);
            }
            return GraceJSONResult.ok(industryVOList);
        }
    }

    /**
     * 查询app端根据一级分类查询三级分类的数据
     *
     * @param thirdListByTopId
     * @return
     */
    @GetMapping("app/getThirdListByTop/{thirdListByTopId}")
    public GraceJSONResult getThirdListByTop(@PathVariable("thirdListByTopId") String thirdListByTopId) {

        List<IndustryVO> industryVOList = new ArrayList<>();
        List<Industry> thirdIndustryList = null;
        String thirdKey = THIRD_INDUSTRY_LIST + ":byId:" + thirdListByTopId;
        String thirdIndustryListStr = redis.get(thirdKey);
        if (StringUtils.isNotBlank(thirdIndustryListStr)) {
            thirdIndustryList = GsonUtils.stringToListAnother(thirdIndustryListStr, Industry.class);
            for (Industry industry : thirdIndustryList) {
                IndustryVO industryVO = new IndustryVO();
                BeanUtils.copyProperties(industry, industryVO);
                industryVOList.add(industryVO);
            }
            return GraceJSONResult.ok(industryVOList);
        } else {
            thirdIndustryList = industryService.getThirdListByTopId(thirdListByTopId);
            String thirdIndustryListString = GsonUtils.object2String(thirdIndustryList);
            redis.set(thirdKey, thirdIndustryListString);
            for (Industry industry : thirdIndustryList) {
                IndustryVO industryVO = new IndustryVO();
                BeanUtils.copyProperties(industry, industryVO);
                industryVOList.add(industryVO);
            }
            return GraceJSONResult.ok(industryVOList);
        }
    }

    /**
     * 使用延迟消息队列发送消息
     *
     * @return
     */
    @PostMapping("refreshIndustry")
    public GraceJSONResult refreshIndustry() {

        // TODO 假设凌晨3点才会执行
        // TODO 获取明天03:00:00的字符串格式
        // TODO 假设是用LocalDateTimeUtils来获取
        // TODO 注意: 假设是用LocalDateTimeUtils来获取, 所以需要引入joda-time依赖
        // LocalDateUtils.getTomorrow() 获取明天的00:00:00
        // LocalDateUtils.getTomorrow() + " 03:00:00" 获取明天03:00:00的字符串格式
        String dataTimes = LocalDateUtils.getTomorrow() + " 03:00:00";

        // TODO 计算凌晨3点到现在的时间
        LocalDateTime futureTimes = LocalDateUtils.parseLocalDateTime(dataTimes, LocalDateUtils.DATETIME_PATTERN);

        // TODO 计算当前时间和凌晨发布的时间差
        long publishTimes = LocalDateUtils.getChronoUnitBetween(LocalDateTime.now(),
                futureTimes,
                ChronoUnit.MILLIS,
                true);

        // TODO 转换成Integer类型
        // Integer daleyTimes = (int) publishTimes;

        // TODO 假设10s后才需要执行
        Integer times = 1000;

        // TODO 发送消息到延迟消息队列
        // 发送延迟队列
        MessagePostProcessor processor = DelayConfig_Industry.setDelayTimes(times);
        // 发送延迟消息
        rabbitTemplate.convertAndSend(
                DelayConfig_Industry.EXCHANGE_DELAY_REFRESH,
                DelayConfig_Industry.DELAY_REFRESH_INDUSTRY,
                "123456",
                processor);

        return GraceJSONResult.ok();
    }

    /**
     * 重置redis的list,在新增 删除 修改的时候
     *
     * @param industry
     */
    private void resetRedisIndustry(Industry industry) {

        Integer level = industry.getLevel();

        // TODO 如果是一级节点那么直接清除掉redis中的数据重新写入
        if (Objects.equals(level, FIRST_NODE)) {
            // TODO 直接删除redis中的数据
            redis.del(TOP_INDUSTRY_LIST);
        }

        // TODO 如果是三级节点那么清除掉redis中的数据重新写入
        if (Objects.equals(level, THIRD_NODE)) {

            // TODO 通过三级节点的id查询一级节点的数据
            String thirdListByTopId = industryService.getTopIndustryId(industry.getId());
            // TODO 获取三级节点的父id
            String thirdKey = THIRD_INDUSTRY_LIST + ":byId:" + thirdListByTopId;
            // TODO 直接删除redis中的数据
            redis.del(thirdKey);

        }
    }

}












































